import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {StorageProvider} from "@providers/storage";
import {Platform} from "ionic-angular";

declare let AMap;

@Injectable()
export class MapProvider {
  private map = null;
  private element: Element = null;
  marker: any;//标记对象

  placeSearch: any;//placeSearch对象

  currentLocation: any;//用户当前位置

  constructor(private storageService: StorageProvider,
              private platform: Platform) {
    this.currentLocation = this.storageService.read("UserLocation");
  }

  newMap() {
    this.map = new AMap.Map('iCenter');
  }

  /**
   * 创建地图
   * @param mapEl  map容器DOM
   * @param mapOptions 参数设置
   * @returns {Promise<T>}
   */
  createMap(mapEl: Element, mapOptions?: any): Promise<any> {
    this.element = mapEl;

    return new Promise((resolve: Function, reject: Function) => {
      try {
        let options = Object.assign({
          resizeEnable: true,
          zoom: 13,
          // center: [this.currentLocation.lng, this.currentLocation.lat]
        }, mapOptions);
        this.map = new AMap.Map(mapEl, options);
        this.map.on('complete', () => {
          AMap.plugin(['AMap.ToolBar', 'AMap.Scale'], () => {
            this.map.addControl(new AMap.ToolBar());
            this.map.addControl(new AMap.Scale());
          });
          resolve(this.map);
        });
      } catch (err) {
        reject('地图加载失败,请检查网络或稍后再试:' + err);
      }
    });
  }

  /***
   * 调用高德地图,显示当前位置
   * ref: https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete
   * @param geolocationOptions 参数设置
   * @returns {Observable}
   */
  displayCurrentPosition(geolocationOptions?: any): Observable<any> {
    return new Observable((sub: any) => {
      this.getGeolocationByAMap(geolocationOptions).subscribe(data => {
        sub.next(data);
        sub.complete();

      }, error => {
        sub.error(error);
      });
    });
  }

  /**
   * web定位
   * @param geolocationOptions  参数设置
   * @returns Observable
   */
  getGeolocationByAMap(geolocationOptions?: any): Observable<any> {
    return new Observable((sub: any) => {
      let map = this.map;
      map.plugin('AMap.Geolocation', () => {
        let options = Object.assign({
          enableHighAccuracy: true,//是否使用高精度定位，默认:true
          timeout: 10000,          //超过10秒后停止定位，默认：无穷大
          buttonOffset: new AMap.Pixel(10, 60),//定位按钮与设置的停靠位置的偏移量，默认：Pixel(10, 20)
          zoomToAccuracy: true,      //定位成功后调整地图视野范围使定位位置及精度范围视野内可见，默认：false
          buttonPosition: 'LB',
          showCircle: true,        //定位成功后用圆圈表示定位精度范围，默认：true
          panToLocation: true,
          useNative: this.platform.is('cordova')         //是否使用 SDK定位
        }, geolocationOptions);

        let geolocation = new AMap.Geolocation(options);
        map.addControl(geolocation);

        geolocation.getCurrentPosition((status, result) => {
          if (status == 'complete') {
            // 存储当前城市
            this.currentLocation = {'lng': result.position.getLng(), 'lat': result.position.getLat()};
            this.storageService.write('UserLocation', this.currentLocation);
            // localStorage.setItem('citycode', data.addressComponent.citycode);
            // localStorage.setItem('city', data.addressComponent.city);
            sub.next(result);
            sub.complete();
          } else {
            // console.log("geolocation error", result);
            // sub.error(result);
          }
        });
      });
    });
  }

  /***
   * 获取地图容器
   * @returns {Element}
   */
  get mapElement(): Element {
    return this.element;
  }

  /***
   * trigger map resize event
   */
  resizeMap(): void {
    if (this.map) {
      AMap.event.trigger(this.map, 'resize');
    }
  }

  /***
   * 自动补全关键词
   * @param keyword: 关键词
   * @param autoOptions: 参数设置
   * @returns {Observable}
   */
  autoComplete(keyword: string, autoOptions?: any): Observable<any> {
    return new Observable((sub: any) => {
      AMap.plugin(['AMap.Autocomplete'], () => {
        let autoOption = Object.assign({
          // city: localStorage.getItem('citycode') //城市，默认全国
        }, autoOptions);
        let autocomplete = new AMap.Autocomplete(autoOption);
        autocomplete.search(keyword, (status, result) => {
          //note:这里用三个等号(===如果类型不同，其结果就是不等;高级类型，==和===是没有区别的,进行“指针地址”比较)
          if ('complete' === status && 'OK' === result.info) {
            sub.next(result.tips);
            sub.complete();
          } else if ("no_data" === status) {
            sub.next("no_data");
            sub.complete();
          } else { //status为error
            console.log(result);
            sub.error(result);
          }
        });
      });
    });
  }

  /***
   * 搜索指定地名
   * @param place 地名
   * @param placeSearchOptions 参数设置
   * @returns {Observable}
   */
  //高德搜索出来的数据是很多的,不是唯一的
  searchPlace(place: any, placeSearchOptions?: any): Observable<any> {
    return new Observable((sub: any) => {
      // note:也可以加载js的时候把插件顺带加载
      // 清除所有marker
      // AMap.clear();
      // this.map.clearMap();

      let options = Object.assign({
        map: this.map,
        city: '湖北'
      }, placeSearchOptions);
      AMap.service(["AMap.PlaceSearch"], () => {
        this.placeSearch = new AMap.PlaceSearch(options);  //构造地点查询类
        // placeSearch.setCity(place.adcode);
        this.placeSearch.search(place, (status, result) => {
          console.log(result);
          if ('complete' === status && 'OK' === result.info) {
            sub.next(result);
            sub.complete();
          } else if ("no_data" === status) {
            sub.next("no_data");
            sub.complete();
          } else { //status为error
            sub.error(result);
          }
        });
      });
    });
  }

  /**
   * 使用placeSearch后POI在地图中对应的Marker被点击时触发
   * @returns {any}
   */
  placeSearchMarkerClick() {
    return Observable.create(observer => {
      try {
        AMap.event.addListener(this.placeSearch, 'markerClick', function (data) {
          observer.next(data);
        });
      } catch (err) {
        observer.error(err);
      }
    });
  }

  /***
   * 搜索周边
   * @param cpoint 中心点坐标 [116.405467, 39.907761]
   * @param type:类型
   * @param radius:半径
   * @param placeSearchOptions 参数配置
   * @returns {Observable}
   */
  searchNearby(cpoint: any, type: string, radius: number, placeSearchOptions?: any): Observable<any> {
    return new Observable((sub: any) => {
      //清除所有marker
      // AMap.clear();
      // this.map.clearMap();

      let options = Object.assign({
        pageSize: 10,
        type: type,
        pageIndex: 1,
      }, placeSearchOptions);
      AMap.service(["AMap.PlaceSearch"], () => {
        let placeSearch = new AMap.PlaceSearch(options);  //构造地点查询类
        placeSearch.searchNearBy('', cpoint, radius, (status, result) => {
          if ('complete' === status && 'OK' === result.info) {
            sub.next(result);
            sub.complete();
          } else if ("no_data" === status) {
            sub.next("no_data");
            sub.complete();
          } else { //status为error
            sub.error(result);
          }
        });
      })
    });
  }

  /**
   * 添加marker
   * @param position   坐标{'lng':15,'lat':15}
   * @param markerOptions   参数设置
   * @returns {AMap.Marker}
   */
  addMarker(position, markerOptions?: any): any {
    let lngX = position.lng;
    let latY = position.lat;
    //http://webapi.amap.com/theme/v1.3/markers/n/mark_b1.png
    let markerOption = Object.assign({
      map: this.map,
      icon: "http://webapi.amap.com/theme/v1.3/markers/n/mark_r.png",
      /* icon: "http://webapi.amap.com/theme/v1.3/markers/n/mark_b" + (index + 1) + ".png",*/
      position: [lngX, latY],
      topWhenMouseOver: true
    }, markerOptions);
    return new AMap.Marker(markerOption);
  }

  /**
   * 添加infowindow
   * @param mar  标记
   * @param content  信息窗口DOM
   * @param infoWindowOptions  参数设置
   */
  addInfoWindow(mar, content, infoWindowOptions?: any) {
    let options = Object.assign({
      content: content,
      autoMove: true,
      offset: new AMap.Pixel(0, -30),
      closeWhenClickMap: true
    }, infoWindowOptions);
    let infoWindow = new AMap.InfoWindow(options);

    AMap.event.addListener(mar, 'click', (e) => {
      infoWindow.open(this.map, mar.getPosition());
    });
  }

  parseStr(p) {
    if (!p || p == "undefined" || p == " undefined" || p == "tel") {
      p = "暂无";
    }
    return p;
  }

  /**
   * 根据经纬坐标获取对应的地址
   * @param position  坐标 [116.40, 39.99];
   */
  poToAddress(position) {
    return Observable.create(observer => {
      let geocoder = new AMap.Geocoder({
        radius: 1000,
        extensions: "all"
      });
      geocoder.getAddress(position, (status, result) => {
        if (status === 'complete' && result.info === 'OK') {
          //获得了有效的地址信息:
          observer.next(result.regeocode);
          observer.complete();
        } else {
          observer.error('根据经纬坐标获取对应的地址失败');
        }
      });
    });

  }

  citySearch(): Promise<any> {
    return new Promise<any>((resolve, reject) => {
      AMap.plugin(['AMap.CitySearch'], () => {
        let citySearch = new AMap.CitySearch();
        citySearch.getLocalCity(function (status, result) {
          if (status === 'complete' && result.info === 'OK') {
            resolve(result)
          }
        })
      });
    });
  }

  initialization() {
    this.citySearch().then(v => sessionStorage.setItem("AMap.adcode", v['adcode']));
  }
}
